package com.yupi.yoj.controller;

import cn.hutool.json.JSONUtil;
import com.yupi.yoj.annotation.AuthCheck;
import com.yupi.yoj.common.BaseResponse;
import com.yupi.yoj.common.DeleteRequest;
import com.yupi.yoj.common.ErrorCode;
import com.yupi.yoj.common.ResultUtils;
import com.yupi.yoj.constant.QueueConstant;
import com.yupi.yoj.constant.UserConstant;
import com.yupi.yoj.exception.BusinessException;
import com.yupi.yoj.exception.ThrowUtils;
import com.yupi.yoj.model.dto.contest.ContestAddRequest;
import com.yupi.yoj.model.dto.contest.ContestQueryTeamListByTidsRequest;
import com.yupi.yoj.model.dto.contest.ContestUpdateRequest;
import com.yupi.yoj.model.entity.Contest;
import com.yupi.yoj.model.vo.ContestVO;
import com.yupi.yoj.service.ContestService;
import com.yupi.yoj.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
 * 帖子接口
 *
 * @author <a href="https://github.com/liyupi">程序员鱼皮</a>
 * @from <a href="https://yupi.icu">编程导航知识星球</a>
 */
@RequestMapping("/contest")
@RestController
@Slf4j
public class ContestController {

    @Resource
    private ContestService contestService;

    @Autowired
    RabbitTemplate rabbitTemplate;

    // region 增删改查

    /**
     * 创建
     *
     * @param contestAddRequest
     * @return
     */
    @PostMapping("/add")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Long> addContest(@RequestBody ContestAddRequest contestAddRequest) {
        if (contestAddRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        Contest contest = new Contest();
        BeanUtils.copyProperties(contestAddRequest, contest);

        List<Integer> tscores = contestAddRequest.getTscores();
        List<Long> tids = contestAddRequest.getTids();
        // 分数列表
        if (tscores != null) {
            contest.setTscores(JSONUtil.toJsonStr(tscores));
        }
        // 题目id列表
        if (tids != null) {
            contest.setTids(JSONUtil.toJsonStr(tids));
        }
        contestService.validContest(contest);
        boolean result = contestService.save(contest);
        long newContestId = contest.getId();
        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);

        return ResultUtils.success(newContestId);
    }

    /**
     * 删除
     *
     * @param deleteRequest
     * @param request
     * @return
     */
    @PostMapping("/delete")
    public BaseResponse<Boolean> deleteContest(@RequestBody DeleteRequest deleteRequest, HttpServletRequest request) {
        if (deleteRequest == null || deleteRequest.getId() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        long id = deleteRequest.getId();
        // 判断是否存在
        Contest oldContest = contestService.getById(id);
        ThrowUtils.throwIf(oldContest == null, ErrorCode.NOT_FOUND_ERROR);

        boolean b = contestService.removeById(id);
        return ResultUtils.success(b);
    }

    /**
     * 更新（仅管理员）
     *
     * @param contestUpdateRequest
     * @return
     */
    @PostMapping("/update")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Boolean> updateContest(@RequestBody ContestUpdateRequest contestUpdateRequest) {
        if (contestUpdateRequest == null || contestUpdateRequest.getId() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        Contest contest = new Contest();
        BeanUtils.copyProperties(contestUpdateRequest, contest);

        List<Integer> tscores = contestUpdateRequest.getTscores();
        List<Long> tids = contestUpdateRequest.getTids();
        // 分数列表
        if (tscores != null) {
            contest.setTscores(JSONUtil.toJsonStr(tscores));
        }
        // 题目id列表
        if (tids != null) {
            contest.setTids(JSONUtil.toJsonStr(tids));
        }

        // 参数校验
        contestService.validContest(contest);

        long id = contestUpdateRequest.getId();
        // 判断是否存在
        Contest oldContest = contestService.getById(id);
        ThrowUtils.throwIf(oldContest == null, ErrorCode.NOT_FOUND_ERROR);
        boolean result = contestService.updateById(contest);
        return ResultUtils.success(result);
    }

    /**
     * 根据 id 获取
     *
     * @param id
     * @return
     */
    @GetMapping("/get/vo")
    public BaseResponse<ContestVO> getContestVOById(long id) {
        if (id <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        Contest contest = contestService.getById(id);
        if (contest == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR);
        }
        return ResultUtils.success(contestService.getContestVO(contest));
    }
    @PostMapping("/list")
    public BaseResponse<List<ContestVO>> listContest() {
        List<Contest> contestUserList = contestService.list();
        ThrowUtils.throwIf(contestUserList==null, ErrorCode.NOT_FOUND_ERROR, "题目库为空");
        List<ContestVO> contestUserVO = contestService.getContestVO(contestUserList);
        // 按时间升序排列
        Collections.sort(contestUserVO, new Comparator<ContestVO>() {
            @Override
            public int compare(ContestVO o1, ContestVO o2) {
                return o1.getStarttime().compareTo(o2.getStarttime());
            }
        });
        return ResultUtils.success(contestUserVO);
    }
    /**
     * 分页获取列表（仅管理员）
     *
     * @param contestQueryRequest
     * @return
     */
   /* @PostMapping("/list/page")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Page<Contest>> listContestByPage(@RequestBody ContestQueryRequest contestQueryRequest) {
        long current = contestQueryRequest.getCurrent();
        long size = contestQueryRequest.getPageSize();
        Page<Contest> contestPage = contestService.page(new Page<>(current, size),
                contestService.getQueryWrapper(contestQueryRequest));
        return ResultUtils.success(contestPage);
    }*/

    /**
     * 分页获取列表（封装类）
     *
     * @param contestQueryRequest
     * @param request
     * @return
     */
   /* @PostMapping("/list/page/vo")
    public BaseResponse<Page<ContestVO>> listContestVOByPage(@RequestBody ContestQueryRequest contestQueryRequest,
            HttpServletRequest request) {
        long current = contestQueryRequest.getCurrent();
        long size = contestQueryRequest.getPageSize();
        // 限制爬虫
        ThrowUtils.throwIf(size > 20, ErrorCode.PARAMS_ERROR);
        Page<Contest> contestPage = contestService.page(new Page<>(current, size),
                contestService.getQueryWrapper(contestQueryRequest));
        return ResultUtils.success(contestService.getContestVOPage(contestPage, request));
    }*/

    /**
     * 分页获取当前用户创建的资源列表
     *
     * @param contestQueryRequest
     * @param request
     * @return
     */
  /*  @PostMapping("/my/list/page/vo")
    public BaseResponse<Page<ContestVO>> listMyContestVOByPage(@RequestBody ContestQueryRequest contestQueryRequest,
            HttpServletRequest request) {
        if (contestQueryRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        User loginUser = userService.getLoginUser(request);
        contestQueryRequest.setUserId(loginUser.getId());
        long current = contestQueryRequest.getCurrent();
        long size = contestQueryRequest.getPageSize();
        // 限制爬虫
        ThrowUtils.throwIf(size > 20, ErrorCode.PARAMS_ERROR);
        Page<Contest> contestPage = contestService.page(new Page<>(current, size),
                contestService.getQueryWrapper(contestQueryRequest));
        return ResultUtils.success(contestService.getContestVOPage(contestPage, request));
    }*/

    // endregion

    /**
     * 返回最近两场竞赛（正在进行或未进行）
     */
    @GetMapping("/getTwoCurrent")
    public BaseResponse<List<ContestVO>> getTwoCurrent() {
        List<Contest> contestList = contestService.getTwoCurrent();
        return ResultUtils.success(contestService.getContestVO(contestList));
    }

    /**
     * 返回已经结束的竞赛
     */
    @GetMapping("/getEndContest")
    public BaseResponse<List<ContestVO>> getEndContest() {
        List<Contest> contestList = contestService.getEndContest();
        return ResultUtils.success(contestService.getContestVO(contestList));
    }

}
